package com.example.amusic.service

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class PlayerControllerImpl(
    private val player: Player
) : PlayerController, CoroutineScope by MainScope() {
    private val _playList = MutableLiveData((emptyList<MediaItem>()))
    override val playList: MutableLiveData<List<MediaItem>>
        get() = _playList

    private val _currentSong = MutableLiveData<MediaItem?>(null)
    override val currentSong: MutableLiveData<MediaItem?>
        get() = _currentSong

    private val _playState = MutableStateFlow<PlayState>(PlayState.Idle)
    override val playState: MutableStateFlow<PlayState>
        get() = _playState

    private val _playProgress = MutableStateFlow<Long>(0)
    override val playProgress: MutableStateFlow<Long>
        get() = _playProgress

    private val _bufferingPercent = MutableStateFlow<Long>(0)
    override val bufferingPercent: MutableStateFlow<Long>
        get() = _bufferingPercent

    //TODO 暂时写 0，后面根据缓存文件的值来获取正确的
    private val _playMode = MutableStateFlow<PlayMode>(PlayMode.valueOf(0))
    override val playMode: MutableStateFlow<PlayMode>
        get() = _playMode

    init {
        player.playWhenReady = true
        player.addListener(object : Player.Listener {
            override fun onPlaybackStateChanged(playbackState: Int) {
                super.onPlaybackStateChanged(playbackState)
                when (playbackState) {
                    Player.STATE_IDLE -> {
                        _playState.value = PlayState.Idle
                        _playProgress.value = 0
                        _bufferingPercent.value = 0
                    }

                    Player.STATE_BUFFERING -> {
                        _playState.value = PlayState.Preparing
                    }

                    Player.STATE_READY -> {
                        player.play()
                        _playState.value = PlayState.Playing
                    }

                    Player.STATE_ENDED -> {

                    }
                }
            }


            override fun onIsPlayingChanged(isPlaying: Boolean) {
                super.onIsPlayingChanged(isPlaying)
                if (player.playbackState == Player.STATE_READY) {
                    _playState.value = if (isPlaying) PlayState.Playing else PlayState.Pause
                }
            }

            override fun onPlayerError(error: PlaybackException) {
                super.onPlayerError(error)
                stop()
                Log.e("TAG", "onPlayerError: 播放出错了，现在切换到下一首进行播放")
                next()
            }

//            override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
//                super.onMediaItemTransition(mediaItem, reason)
//                mediaItem ?: return
//                val playList = _playList.value ?: return
//                Log.e("TAG_MUSIC", "回调了 onMediaItemTransition: mediaItem=${mediaItem} reason=${reason} mediaItem.mediaId=${mediaItem.mediaId}")
//                _currentSong.value = playList.find { it.mediaId == mediaItem.mediaId }
//                Log.e("TAG_MUSIC", "当前歌曲是 ${_currentSong.value}")
//
//            }

        })
        setPlayMode(PlayMode.valueOf(0))
//        launch(Dispatchers.Main.immediate) {  }

        launch {
            while (true) {
                if (player.isPlaying) {
                    _playProgress.value = player.currentPosition
                }
                delay(980)
            }
        }
    }


    override fun addAndPlay(song: MediaItem) {
        TODO("Not yet implemented")
    }

    override fun replaceAll(songList: List<MediaItem>, song: MediaItem) {
        launch(Dispatchers.Main.immediate) {
            withContext(Dispatchers.IO) {
                //处理数据库的相关内容，后续实现
            }
            stop()
            player.setMediaItems(songList)
            _playList.value = songList
            _currentSong.value = song
            play(song.mediaId)
        }
    }

    override fun play(mediaId: String) {
        val playList = _playList.value
        if (playList.isNullOrEmpty()) {
            return
        }
        val index = playList.indexOfFirst { it.mediaId == mediaId }
        if (index < 0) {
            return
        }
        stop()
        player.seekTo(index, 0)
        player.prepare()
        _currentSong.value = playList[index]
        _playProgress.value = 0
        _bufferingPercent.value = 0
    }

    override fun delete(song: MediaItem) {
    }

    override fun clearPlayList() {
    }

    override fun playPause() {
        if (player.mediaItemCount == 0) return
        when (player.playbackState) {
            Player.STATE_IDLE -> {
                player.prepare()
            }

            Player.STATE_BUFFERING -> {
                stop()
            }

            Player.STATE_READY -> {
                if (player.isPlaying) {
                    player.pause()
                    _playState.value = PlayState.Pause
                } else {
                    player.play()
                    _playState.value = PlayState.Playing
                }
            }

            Player.STATE_ENDED -> {
                player.seekToNextMediaItem()
                player.prepare()
            }
        }
    }

    override fun next() {
        if (player.mediaItemCount == 0) return
        player.seekToNextMediaItem()
        player.prepare()
        _playProgress.value = 0
        _bufferingPercent.value = 0
    }

    override fun prev() {
        if (player.mediaItemCount == 0) return
        player.seekToPreviousMediaItem()
        player.prepare()
        _playProgress.value = 0
        _bufferingPercent.value = 0
    }

    override fun seekTo(msec: Int) {
    }

    override fun getAudioSession(): Int {
        return 0
    }

    override fun setPlayMode(mode: PlayMode) {
    }

    override fun stop() {
        player.stop()
        _playState.value = PlayState.Idle
    }

}